package com.luyuan.framework.web.service;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSONObject;
import com.luyuan.common.constant.Constants;
import com.luyuan.common.core.domain.entity.WxappUser;
import com.luyuan.common.core.domain.model.WxappLoginUser;
import com.luyuan.common.core.domain.model.WxappUserResponse;
import com.luyuan.common.utils.MessageUtils;
import com.luyuan.common.utils.StringUtils;
import com.luyuan.common.utils.bean.BeanUtils;
import com.luyuan.common.utils.weixin.WxappUtil;
import com.luyuan.framework.config.properties.WxappProperties;
import com.luyuan.framework.manager.AsyncManager;
import com.luyuan.framework.manager.factory.AsyncFactory;
import com.luyuan.system.service.IWxappUserService;

/**
 * 微信小程序用户登录服务
 * 
 * @author luyuan
 */
@Service
public class WxappUserService {
    private static final Logger log = LoggerFactory.getLogger(WxappUserService.class);

    @Autowired
    private WxappProperties wxappProperties;

    @Autowired
    private IWxappUserService wxappUserService;

    @Autowired
    private WxappTokenService wxappTokenService;

    /**
     * 微信小程序登录
     * 
     * @param code          微信登录code
     * @param encryptedData 加密数据
     * @param iv            初始向量
     * @return 登录结果
     */
    public WxappUserResponse login(String code, String encryptedData, String iv) {
        try {
            // 1. 调用微信接口获取session_key和openid
            JSONObject session = WxappUtil.getSessionByCode(wxappProperties.getAppid(),
                    wxappProperties.getSecret(), code);

            if (session == null) {
                throw new RuntimeException("微信登录失败");
            }

            // 获取openid和session_key
            String openid = session.getString("openid");
            String sessionKey = session.getString("session_key");

            if (StringUtils.isEmpty(openid)) {
                throw new RuntimeException("获取微信用户信息失败");
            }

            // 2. 解密用户信息
            JSONObject userInfo = null;
            if (StringUtils.isNotEmpty(encryptedData) && StringUtils.isNotEmpty(iv)) {
                userInfo = WxappUtil.decryptUserInfo(encryptedData, sessionKey, iv);
            }
             WxappUserResponse loginUserResponse = new WxappUserResponse();
            // 3. 根据openid查找或创建用户
            WxappUser user = wxappUserService.selectWxappUserByOpenid(openid);
            if (user == null) {
                // 用户不存在，创建新用户
                user = createUser(openid, userInfo);
            } else if (userInfo != null) {
                // 用户存在且有新的用户信息，更新用户信息
                updateUser(user, userInfo);
            }
            // 4. 生成登录用户对象（微信小程序用户没有权限控制）
            WxappLoginUser loginUser = new WxappLoginUser(user.getUserId(), user, null);
            BeanUtils.copyProperties(user, loginUserResponse);
            // 5. 生成令牌
            String token = wxappTokenService.createToken(loginUser);
            loginUserResponse.setToken(token);
            return loginUserResponse;
        } catch (Exception e) {
            log.error("微信登录失败", e);
            throw new RuntimeException("登录失败: " + e.getMessage());
        }
    }

    /**
     * 微信小程序退出登录
     * 
     * @param request
     * @return 退出登录结果
     */
    public String logout(HttpServletRequest request) {
        try {
            WxappLoginUser loginUser = wxappTokenService.getWxappLoginUser(request);
            if (loginUser != null) {
                // 删除用户缓存记录
                wxappTokenService.delWxappLoginUser(loginUser.getToken());
                // 记录用户退出日志
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUsername(), Constants.LOGOUT,
                        MessageUtils.message("user.logout.success")));
                return "退出成功";
            } else {
                return "用户未登录";
            }
        } catch (Exception e) {
            log.error("退出失败", e);
            throw new RuntimeException("退出失败: " + e.getMessage());
        }
    }

    /**
     * 获取微信用户手机号
     * 
     * @param code          微信登录code
     * @param encryptedData 加密数据
     * @param iv            初始向量
     * @return 手机号信息
     */
    public JSONObject getPhoneNumber(String code, String encryptedData, String iv) {
        try {
            // 1. 调用微信接口获取session_key
            JSONObject session = WxappUtil.getSessionByCode(wxappProperties.getAppid(),
                    wxappProperties.getSecret(), code);

            if (session == null) {
                throw new RuntimeException("获取微信session失败");
            }

            // 获取session_key
            String sessionKey = session.getString("session_key");

            if (StringUtils.isEmpty(sessionKey)) {
                throw new RuntimeException("获取微信session_key失败");
            }

            // 2. 解密手机号信息
            if (StringUtils.isNotEmpty(encryptedData) && StringUtils.isNotEmpty(iv)) {
                JSONObject phoneInfo = WxappUtil.decryptUserInfo(encryptedData, sessionKey, iv);
                return phoneInfo;
            } else {
                throw new RuntimeException("加密数据或初始向量不能为空");
            }
        } catch (Exception e) {
            log.error("获取微信手机号失败", e);
            throw new RuntimeException("获取手机号失败: " + e.getMessage());
        }
    }

    /**
     * 创建新用户
     * 
     * @param openid   微信openid
     * @param userInfo 用户信息
     * @return 微信小程序用户
     */
    private WxappUser createUser(String openid, JSONObject userInfo) {
        WxappUser user = new WxappUser();
        user.setOpenid(openid);

        // 如果有用户信息，则设置用户信息
        if (userInfo != null) {
            user.setNickName(userInfo.getString("nickName"));
            user.setSex(userInfo.getString("gender"));
            user.setAvatarUrl(userInfo.getString("avatarUrl"));
            user.setCity(userInfo.getString("city"));
            user.setProvince(userInfo.getString("province"));
            user.setCountry(userInfo.getString("country"));
            user.setLanguage(userInfo.getString("language"));
        } else {
            user.setNickName("微信用户");
        }

        user.setStatus("0"); // 正常状态
        user.setDelFlag("0"); // 未删除

        // 插入用户信息
        wxappUserService.insertWxappUser(user);

        return user;
    }

    /**
     * 更新用户信息
     * 
     * @param user     微信小程序用户
     * @param userInfo 用户信息
     */
    private void updateUser(WxappUser user, JSONObject userInfo) {
        user.setNickName(userInfo.getString("nickName"));
        user.setSex(userInfo.getString("gender"));
        user.setAvatarUrl(userInfo.getString("avatarUrl"));
        user.setCity(userInfo.getString("city"));
        user.setProvince(userInfo.getString("province"));
        user.setCountry(userInfo.getString("country"));
        user.setLanguage(userInfo.getString("language"));
        wxappUserService.updateWxappUser(user);
    }

    /**
     * 更新微信小程序用户信息
     * 
     * @param user 微信小程序用户
     * @return 结果
     */
    public int updateWxappUser(WxappUser user) {
        return wxappUserService.updateWxappUser(user);
    }
}